﻿//===========================[ 8 / 16 / 2011 LVI ]=============================
//				Copyright c Vitaly Lyaschenko <SkyChameleon@gmail.com>
//								Source file
// Purpose: 
//=============================================================================
#include "BaseGeometry.h"
#include "Vertices.h"
#include "Kernel.h"

///////////////////////////////////////////////////////////////////////////
// 
dbgGrid::dbgGrid( int sizeX, int sizeY, float stride )
{
	createGrid( vertex, sizeX, sizeY, stride );
}

void dbgGrid::init(cEffect *pEffect)
{
	this->m_pEffect = pEffect;
	identity(mtrModel);
	coutVertex = vertex.size();
	int   sizeofVert = (sizeof(float)*3) * coutVertex;
	void *dataVert = vertex.data();

	// создание и биндинг 1 VAO для сетки
	m_VAO = m_pRender->createVArray();
	m_VAO->Create();

	// создаем VBO(Vertex Buffer Object) для позиции вершин
	m_VBO_Pos =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_POSITION, 3, sizeof(float)*3, (void *) 0 );
	m_VAO->Unbind();
}

dbgGrid::~dbgGrid()
{
	vertex.clear();

	SAFE_DELETE(m_VAO);
	SAFE_DELETE(m_VBO_Pos);
}

void dbgGrid::draw()
{
	m_pEffect->setMtrModel( mtrModel );
	m_pRender->setDrawPrimitiveMode( Lines );

	m_VAO->Bind();
	m_pRender->drawArrays( 0, coutVertex );
	m_VAO->Unbind();
}

///////////////////////////////////////////////////////////////////////////
// координатная сетка
CoorGrid::CoorGrid( int sizeX, int sizeY, float stride )
{
	createCoorGrid( vertex, sizeX, sizeY, stride );
}

void CoorGrid::init( cEffect *pEffect )
{
	identity(mtrModel);
	mtrModel = fromEuler( 90, 0, 0 );

	this->m_pRender = Kernel::spec().getRender();
	this->m_pEffect = pEffect;

	coutVertex = vertex.size();
	int   sizeofVert = sizeof(Vertex_pc) * coutVertex;
	void *dataVert = vertex.data();

	// создание и биндинг 1 VAO для сетки
	m_VAO = m_pRender->createVArray();
	m_VAO->Create();

	// создаем VBO(Vertex Buffer Object) для позиции вершин
	m_VBO_Pos =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_POSITION, 3, sizeof(Vertex_pc), (void *) 0 );

	m_VBO_Color =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_COLOR, 3, sizeof(Vertex_pc), (void *)(sizeof(float) * 3) );

	m_VAO->Unbind();
}

CoorGrid::~CoorGrid()
{
	vertex.clear();

	SAFE_DELETE(m_VAO);
	SAFE_DELETE(m_VBO_Pos);
	SAFE_DELETE(m_VBO_Color);
}

void CoorGrid::draw()
{
	m_pEffect->setMtrModel( mtrModel );
	m_pRender->setDrawPrimitiveMode( Lines );

	m_VAO->Bind();
	m_pRender->drawArrays( 0, coutVertex );
	m_VAO->Unbind();
}

///////////////////////////////////////////////////////////////////////////
// Куб
Box::Box( int size )
{
	createCube( vertex, index, size );
}

void Box::init( cEffect *pEffect )
{
	identity(mtrModel);

	this->m_pRender = Kernel::spec().getRender();
	this->m_pEffect = pEffect;

	coutIndex = index.size();
	int  sizeofVert  = sizeof(Vertex_PNT) * vertex.size();
	int  sizeofIndex = sizeof(_16ubit) * coutIndex;
	void *dataVert   = vertex.data();
	void *dataIndex  = index.data();
	// создание и биндинг 1 VAO для сетки
	m_VAO = m_pRender->createVArray();
	m_VAO->Create();

	// создаем VBO(Vertex Buffer Object) для позиции вершин
	m_VBO_Pos =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_POSITION, 3, sizeof(Vertex_PNT), (void *) 0 );

	m_VBO_Normal =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_NORMAL, 3, sizeof(Vertex_PNT), (void *)(sizeof(float) * 3) );

	m_VBO_TexCoor =  m_pRender->createVBuffer( sizeofVert, dataVert );
	m_pRender->setAttrPtr( VERT_TEXCOORD, 2, sizeof(Vertex_PNT), (void *)(sizeof(float) * 6) );

	m_VBO_Indices =  m_pRender->createVBufferEl( sizeofIndex, dataIndex );

	m_VAO->Unbind();
}

Box::~Box()
{
	SAFE_DELETE( m_VAO );
	SAFE_DELETE( m_VBO_Pos );
	SAFE_DELETE( m_VBO_Normal );
	SAFE_DELETE( m_VBO_TexCoor );
	SAFE_DELETE( m_VBO_Indices );

	vertex.clear();
	index.clear();
}

void Box::draw()
{
	m_pEffect->setMtrModel( mtrModel );

	m_pRender->setDrawPrimitiveMode( Triangles );

	m_VAO->Bind();
	m_pRender->drawElements16( coutIndex );
	m_VAO->Unbind();
}